<?php 
namespace Services;
use \Entity;
use \DbConnection;

/**
 * ????
 *
 * @copyright Copyright (c) 2013
 * @version   1.0
 * 
 * @todo commenter la classe
 **/
class ListAction
{	
	protected $_msg;
	protected $_serviceCtrl;
	protected $_params;

    /**
    * Constructor
    * 
    * @return void
    */    
    public function __construct () {
		$this->_msg = NULL;
    }
	
	/**
	* @todo Tester l'exitance et le type des données (colonnes) et convertir en fonction de ce type
	* @todo Ajouter le système de regles de gestion
	*/
	public function execute($serviceCtrl, $params) {
		$this->_serviceCtrl =$serviceCtrl;
		$this->_params = $params;
		
		$serviceCtrl->writeTrace('[Service\\ListAction] - execute de l\'action LIST');	
		$serviceCtrl->writeTrace('[Service\\ListAction] - entité =', $params['e']);	
		
/*		$serviceCtrl->writeTrace('[Service\\ListAction] - récupération du parametre fields');
		if (isset($params['fields'])) {
			$serviceCtrl->writeTrace('[Service\\ListAction] - fields :', $params['fields']);
			$fields = json_decode($params['fields']);
			//. TODO traiter les erreurs avec json_last_error()
		} else {
			$serviceCtrl->writeTrace('[Service\\ListAction] - parametre fields absent');
			$this->_msg = 'paramètre fields absent';
		}
*/		
		$serviceCtrl->writeTrace('[Service\\ListAction] - recherche de l\'entité avec le code ', $params['e']);
		
		$e = new Entity();
		if (!$e->read($params['e'])){
			$this->_msg = 'entité inconnue - vérifier le code ' . $params['e'];
			return NULL;
		}
		
		$tableName = $e->bddTable;
		$serviceCtrl->writeTrace('[Service\\ListAction] - Nom de la table : ', $tableName);
		
//		$objectid = $e->CreateSysObject($serviceCtrl->getUserMembership()->getUserId());
//		$serviceCtrl->writeTrace('[Service\\ListAction] - Object_id: ', $objectid);
		
		// TODO : filtrer uniquement sur les entités dont l'utilisateur à le droit
		
		$query = 'select id';
		$colOrder = array();	
		$order = 1;	
		$fields = $e->readFields();
		foreach($fields as $key => $val) {
			$colOrder[$order++] = $key;
			$query .= ', `' . $val->sqlColName . '`';
		}
		
		$query .= ' from ' . $tableName;		

		$whereClause = $this->buildFilters($fields);

		if ($whereClause != NULL)
			$query .= $whereClause[0];

		$values	= $whereClause[1];

		$serviceCtrl->writeTrace('[Service\\ListAction] - Requete : ', $query);
				
		$res = array();
		DbConnection::getInstance()->Execute($query, $values);
		
		while ( $row = DbConnection::getInstance()->nextRow())
		{	
			$data = array();
			$data['id'] = (float)$row[0];
			foreach($colOrder as $fieldOrder => $fieldCode) {
				$data[$fieldCode] = $fields[$fieldCode]->cast($row[$fieldOrder]);
			}			
			$res[] = $data;
		}
		
		return $res;
	}	
	
	/**
	* 
	* 
	* @param undefined $fields
	* 
	* @todo creer un objet filtre en Js et le mapper en php pour pouvoir faire des opérations plus complexe ex and / or; > < beetwen like ...
	*/	
	private function buildFilters($fields) {
		$this->_serviceCtrl->writeTrace('[Service\\ListAction::buildFilters] - récupération du parametre filter');
		if (isset($this->_params['filter'])) {
			$this->_serviceCtrl->writeTrace('[Service\\ListAction::buildFilters] - filter :', $this->_params['filter']);
			$filters = json_decode($this->_params['filter']);
			//. TODO traiter les erreurs avec json_last_error()
		} else {
			$this->_serviceCtrl->writeTrace('[Service\\ListAction::buildFilters] - aucun filter');
			return NULL;
		}

	    if($filters == NULL) { // If we couldn't decode the filter
	        return '';
	    }
		
	    $whereClauses = array(); // Stores whereClauses
		$paramValues = array();
	    foreach($filters as $filter) {
			$value = $filter->value;
			$field = '';
			if( property_exists($filter, 'field'))
				$field = $filter->field;
			if( property_exists($filter, 'property'))
				$field = $filter->property;
			
			$sqlParam = $fields[$field]->getSqlParam();
			$whereClauses[] =  $fields[$field]->getSqlColName() . ' = <' . $sqlParam . '/>';
			$paramValues[$sqlParam] = $fields[$field]->cast($filter->value);
			
			
			/*
	        switch($filter->type) {
	            case 'boolean':
	                $filter->value = ($filter->value === TRUE) ? '1' : '0'; // Convert value for DB
	                $whereClauses[] = "$filter->field = $filter->value" ;
	                break;
	            case 'date':
	                $filter->value = "'$filter->value'"; // Enclose data in quotes
	            case 'numeric':
	                switch($filter->comparison) {
	                    case 'lt': // Less Than
	                        $whereClauses[] = "$filter->field < $filter->value";
	                        break;
	                    case 'gt': // Greather Than
	                        $whereClauses[] = "$filter->field > $filter->value";
	                        break;
	                    case 'eq': // Equal To
	                        $whereClauses[] = "$filter->field = $filter->value";
	                        break;
	                }
	                break;
	            case 'list':
	                $listItems = array();
	                foreach($filter->value as $value) {
	                    $listItems[] = "'$value'";
	                }
	                $whereClauses[] = "$filter->field IN(" . implode(',', $listItems) . ')';
	                break;
	            case 'string':
	            default: // Assume string
	                $whereClauses[] = "(
	                    $filter->field LIKE '{$filter->value}%' OR
	                    $filter->field LIKE '%{$filter->value}' OR
	                    $filter->field LIKE '%{$filter->value}%' OR
	                    $filter->field = '{$filter->value}'
	                )";
	                break;
	        }
			*/
	    }
		
	    if(count($whereClauses) > 0) {
	        return array (' WHERE ' . implode(' AND ', $whereClauses), $paramValues);
		}

		return NULL;
	}

} // END class